#include <iostream>
#include <string>
#include <memory>

// 抽象电脑类
class Computer
{
public:
    void setBoard(const std::string &board) { _board = board; }
    void setDisplay(const std::string &display) { _display = display; }
    virtual void setOs() = 0;
    std::string toString()
    {
        std::string computer = "Computer:{\n";
        computer += "\tboard = " + _board + ",\n";
        computer += "\tdisplay = " + _display + ",\n";
        computer += "\tOs = " + _os + ",\n";
        computer += "}\n";
        return computer;
    }

protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

// 具体电脑类
class MacComputer : public Computer
{
public:
    void setOs() override
    {
        _os = "Mac Os";
    }
};

// 抽象建造者类
class Bulider
{
public:
    virtual void build_Board(const std::string &) = 0;
    virtual void build_Display(const std::string &) = 0;
    virtual void build_Os() = 0;
    virtual std::shared_ptr<Computer> build() = 0;
};

// 具体建造类
class MacBuilder : public Bulider
{
public:
    MacBuilder() { _computer = std::make_shared<MacComputer>(); }
    void build_Board(const std::string &board) override
    {
        _computer->setBoard(board);
    }

    void build_Display(const std::string &display) override
    {
        _computer->setDisplay(display);
    }
    void build_Os()
    {
        _computer->setOs();
    }
    std::shared_ptr<Computer> build() override
    {
        return _computer;
    }

private:
    std::shared_ptr<Computer> _computer;
};

class Director
{
public:
    Director(Bulider *builder) : _builder(builder) {}
    void Construct(const std::string &board, const std::string &display)
    {
        _builder->build_Board(board);
        _builder->build_Display(display);
        _builder->build_Os();
    }

private:
    std::shared_ptr<Bulider> _builder;
};

int main()
{
    Bulider *builder = new MacBuilder();
    std::unique_ptr<Director> director = std::make_unique<Director>(builder);
    director->Construct("英特尔主板", "VOC显⽰器");

    std::shared_ptr<Computer> computer = builder->build();
    std::cout << computer->toString() << std::endl;
}